﻿using DreamCMS.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DreamCMS.BLL.Factory;
using DreamCMS.Entity.Common;

namespace DreamCMS.BLL
{
    public class PostManager
    {
        //实例化文章实体的数据访问对象
        private static IPostDAO dao = DataAccessFactory.CreatePostDAO();

        /// <summary>
        /// 列表
        /// </summary>
        private static List<PostInfo> postList;

        /// <summary>
        /// lock
        /// </summary>
        private static object lockHelper = new object();

        static PostManager()
        {
            LoadPost();
        }

        /// <summary>
        /// 初始化，将文章表中数据读入到静态字段postList中
        /// </summary>
        public static void LoadPost()
        {
            if (postList == null)
            {
                lock (lockHelper)
                {
                    if (postList == null)
                    {
                        postList = dao.GetPostList();
                    }
                }
            }
        }
        /// <summary>
        /// 更新文章列表字段postList的缓存
        /// </summary>
        public static void ClearCache()
        {
            postList=dao.GetPostList();
        }

        /// <summary>
        /// 添加文章
        /// </summary>
        /// <param name="post"></param>
        /// <returns></returns>
        public static long InsertPost(PostInfo post)
        {
            post.PostId = dao.InsertPost(post);//插入到数据库
            postList.Add(post); //插入到文章管理器的字段（作缓存）
            postList.Sort();  //更新缓存内的排序（按照文章实体指定的排序方式）

            //更新站点统计表中整站文章数量
            StatisticManager.UpdateStatisticPostCounts(1);
            //更新用户表中当前发表用户的文章数
            UserManager.UpdateUserPostCount(post.UserId, 1);
            //更新分类表中的当前发布的文章所属栏目的文章数量
            CategoryManager.UpdateCategoryCount(post.CategoryId, 1);
            //更新当前文章提交的这几个标签的每个标签的文章数量+1
            TagManager.UpdateTagUseCount(post.Tag, 1);

            return post.PostId;
        }

        /// <summary>
        /// 修改文章
        /// </summary>
        /// <param name="post">文章实体</param>
        /// <returns>修改的文章个数</returns>
        public static long UpdatePost(PostInfo post)
        {
            PostInfo oldPost = GetPostByDatabase(post.PostId);

            long result = dao.UpdatePost(post);

            if (oldPost != null && oldPost.CategoryId != post.CategoryId)
            {
                //分类
                CategoryManager.UpdateCategoryCount(oldPost.CategoryId, -1);
                CategoryManager.UpdateCategoryCount(post.CategoryId, 1);
            }

            //更新标签对应文章数
            TagManager.UpdateTagUseCount(oldPost.Tag, -1);
            TagManager.UpdateTagUseCount(post.Tag, 1);

            return result;
        }

        /// <summary>
        /// 删除文章
        /// </summary>
        /// <param name="postid"></param>
        /// <returns></returns>
        public static long DeletePostById(long postid)
        {
            PostInfo oldPost = GetPost(postid);

            postList.Remove(oldPost);

            long result = dao.DeletePost(postid);

            //统计
            StatisticManager.UpdateStatisticPostCounts(-1);
            //用户
            UserManager.UpdateUserPostCount(oldPost.UserId, -1);
            //分类
            CategoryManager.UpdateCategoryCount(oldPost.CategoryId, -1);
            //标签
            TagManager.UpdateTagUseCount(oldPost.Tag, -1);

            //删除所有评论
            CommentManager.DeleteCommentByPost(postid);
            postList.Sort();
            return result;
        }
        /// <summary>
        /// 根据类别删除文章
        /// </summary>
        /// <param name="catId"></param>
        /// <returns></returns>
        public static long DeletePostsByCat(long catId)
        {
            List<PostInfo> list=GetPostList(-1,catId,-1,PostRecommend.Other,PostStatus.Other,PostTopStatus.Other,PostHideStatus.Other);
            //删除缓存列表中的该类别文章
            foreach(PostInfo p in list)
            {
                postList.Remove(p);
                //删除所有评论
                CommentManager.DeleteCommentByPost(p.PostId);
            }
            //删除数据库中的该类别文章
           

            //更新统计文章数
            StatisticManager.UpdateStatisticPostCounts(-list.Count);
            //TODO:更新用户文章数

            //TODO:更新标签对应文章数

            return dao.DeletePostByCat(catId);
        }

        /// <summary>
        /// 根据Id获取文章（从文章列表的静态缓存中）
        /// </summary>
        /// <param name="postid"></param>
        /// <returns></returns>
        public static PostInfo GetPost(long postid)
        {
            foreach (PostInfo post in postList)
            {
                if (post.PostId == postid)
                {
                    return post;
                }
            }
            return null;
        }

        /// <summary>
        /// 从数据库获取文章
        /// </summary>
        /// <param name="postId"></param>
        /// <returns></returns>
        public static PostInfo GetPostByDatabase(long postId)
        {
            return dao.GetPost(postId);
        }

        /// <summary>
        /// 根据别名获取文章（从静态缓存中）
        /// </summary>
        /// <param name="slug"></param>
        /// <returns></returns>
        public static PostInfo GetPost(string slug)
        {
            foreach (PostInfo post in postList)
            {
                if (!string.IsNullOrEmpty(slug) && post.Slug.ToLower() == slug.ToLower())
                {
                    return post;
                }
            }
            return null;
        }


        /// <summary>
        /// 获取全部文章,（是缓存的）
        /// </summary>
        /// <returns></returns>
        public static List<PostInfo> GetPostList()
        {
            return postList;
        }

        /// <summary>
        /// 获取文章数（由于查询文章数的条件复杂，故是从数据库中进行的查询，而不是缓存）
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="tagId"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static long GetPostCount(long categoryId, long tagId, long userId)
        {
            long recordCount = 0;
            GetPostList(1, 1, out recordCount, categoryId, tagId, userId,PostRecommend.Other, PostStatus.Other,PostTopStatus.Other, PostHideStatus.Other, string.Empty, string.Empty, string.Empty);

            return recordCount;
        }

        /// <summary>
        /// 获取文章数（直接查询数据库，非缓存）
        /// </summary>
        /// <param name="categoryId"></param>
        /// <param name="tagId"></param>
        /// <param name="userId"></param>
        /// <param name="status"></param>
        /// <param name="hidestatus"></param>
        /// <returns></returns>
        public static long GetPostCount(long categoryId, long tagId, long userId, PostStatus status, PostHideStatus hidestatus)
        {
            long recordCount = 0;
            GetPostList(1, 1, out recordCount, categoryId, tagId, userId, PostRecommend.Other, status, PostTopStatus.Other, hidestatus, string.Empty, string.Empty, string.Empty);
            return recordCount;
        }

        /// <summary>
        /// 获取文章页的列表（非缓存）
        /// </summary>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <param name="recordCount"></param>
        /// <param name="type"></param>
        /// <param name="categoryId"></param>
        /// <param name="userId"></param>
        /// <param name="status"></param>
        /// <param name="topstatus"></param>
        /// <param name="keyword"></param>
        /// <returns></returns>
        public static List<PostInfo> GetPostList(long pageSize, long pageIndex, out long recordCount, long categoryId, long tagId, long userId, PostRecommend recommend, PostStatus status, PostTopStatus topstatus, PostHideStatus hidestatus, string begindate, string enddate, string keyword)
        {
            long _recommend = (long)recommend;
            long _status = (long)status;
            long _topstatus = (long)topstatus;
            long _hidestatus = (long)hidestatus;
            List<PostInfo> list = dao.GetPostList(pageSize, pageIndex, out recordCount, categoryId, tagId, userId, _recommend, _status, _topstatus, _hidestatus, begindate, enddate, keyword);
            return list;
        }


        /// <summary>
        /// 获取小型列表（没有分页的那种）（从静态缓存字段）
        /// </summary>
        /// <param name="rowCount">要获取的条数</param>
        /// <param name="categoryId">-1表示不针对该字段进行过滤</param>
        /// <param name="userId">-1表示不针对该字段进行过滤</param>
        /// <param name="recommend">可以传入other枚举作为排除此条件</param>
        /// <param name="status">可以传入other枚举作为排除此条件</param>
        /// <param name="topstatus">可以传入other枚举作为排除此条件</param>
        /// <param name="hidestatus">可以传入other枚举作为排除此条件</param>
        /// <returns></returns>
        public static List<PostInfo> GetPostList(long rowCount, long categoryId, long userId, PostRecommend recommend, PostStatus status, PostTopStatus topstatus, PostHideStatus hidestatus)
        {
            List<PostInfo> list = postList;
            if (categoryId != -1)
            {
                //传入一个委托（动作），调用list的FindAll就会按照委托的这个动作找出符合该动作（调用为true）的元素。
                //因此，我们传入一个判断类别ID是否相等的委托，list中根据该动作判断所有元素，就可以找到用户想要的类别ID
                //这里用到了匿名委托的知识，也就是说没有创建委托类，直接在这里构造了委托实例，编译器自动判断了此处是：参数是PostInfo类型，返回值是bool类型的一个委托类。
                list = list.FindAll(delegate(PostInfo post) { return post.CategoryId == categoryId; });
            }

            if (userId != -1)
            {
                list = list.FindAll(delegate(PostInfo post) { return post.UserId == userId; });
            }
            if ((long)recommend != -1)
            {
                list = list.FindAll(delegate(PostInfo post) { return post.Recommend == recommend; });
            }
            if ((long)status != -1)
            {
                list = list.FindAll(delegate(PostInfo post) { return post.Status == status; });
            }
            if ((long)topstatus != -1)
            {
                list = list.FindAll(delegate(PostInfo post) { return post.TopStatus == topstatus; });
            }
            if ((long)hidestatus != -1)
            {
                list = list.FindAll(delegate(PostInfo post) { return post.HideStatus == hidestatus; });
            }

            if (rowCount > list.Count || rowCount==-1)
            {
                return list;
            }
            List<PostInfo> list2 = new List<PostInfo>();
            for (int i = 0; i < rowCount; i++)
            {
                list2.Add(list[i]);
            }
            return list2;
        }


        /// <summary>
        /// 更新文章点击数
        /// </summary>
        /// <param name="postId"></param>
        /// <param name="addCount"></param>
        /// <returns></returns>
        public static long UpdatePostViewCount(int postId, int addCount)
        {
            PostInfo post = GetPost(postId);

            if (post != null)
            {
                post.ViewCount += addCount;
            }
            return dao.UpdatePostViewCount(postId, addCount);
        }

        /// <summary>
        /// 更新评论数
        /// </summary>
        /// <param name="postId"></param>
        /// <param name="addCount"></param>
        /// <returns></returns>
        public static long UpdatePostCommentCount(long postId, long addCount)
        {
            PostInfo post = GetPost(postId);

            if (post != null)
            {
                post.CommentCount += addCount;

                return dao.UpdatePost(post);
            }
            return 0;

        }

    }
}
